﻿#pragma once

/// 画布
/// 负责绘制， 管理图像

#include "svgshape.h"

constexpr double CANVAS_DEFAULT_WIDTH = 500;
constexpr double CANVAS_DEFAULT_HEIGHT = 500;
static const QColor CANVAS_DEFAULT_BACKGROUND = Qt::white;

class SvgCanvas
{
public:
	SvgCanvas() = default;
	SvgCanvas(double width, double height);

public:
	void Paint(QPainter& painter, const QRect& viewPort);
	void RePaint();
	// 为了方便，用canvas 坐标
	void RePaint(QRectF canvasRect);
	void RePaint(const QRectF& rect1, const QRectF& rect2);

	void AddShape(unique_ptr<SvgShape> shape);
	void DeleteShape(SvgShape* shape);
	void DeleteShapes(const vector<SvgShape*>& shapes);
	void BringShapesToFront(const vector<SvgShape*>& shapes);
	void SendShapesToBack(const vector<SvgShape*>& shapes);

	// 通过坐标获得选中的图形
	SvgShape* GetShapeByCoordinate(QPointF pos) const;
	// 这个需要保证顺序, 旧 -> 新, 0 -> n
	vector<SvgShape*> GetShapeByRect(const QRectF& rect) const;
	SvgShape* GetLastShape() const;

	void ReSize(double width, double height);
	void SetHeight(double height);
	void SetWidth(double width);
	void SetBackground(const QColor& color);
	void SetShapes(SvgShapeVec shapes);
	void SetScale(double scale);

	void SetBasePoint(const QPoint basePoint);
	QPoint GetBasePoint() const;

	double Height() const;
	double Width() const;
	QColor Background() const;

	void Clear();

	bool Save(const QString& path) const;

	QPointF WidgetPosToCanvasPos(const QPointF& p) const;
	QPointF CanvasPosToWidgetPos(const QPointF& p) const;

	// group 应该是有顺序的
	void MakeGroup(const vector<SvgShape*>& group);
	void TranslateGroup(const QRectF& rect);
	void TranslateGroup(const QPointF& pos);
	void GroupRePaint();
	void ClearGroup();

	// 我不得不说，这两个函数不应该存在
	void PainterToViewPortPos(QPainter& painter) const;
	QRect GetViewPort() const;

private:
	QRectF _CanvasRectToWidgetRect(const QRectF& rect) const;
	QRectF _WidgetRectToCanvasRect(const QRectF& rect) const;

	void _InitPainter(QPainter& painter, const QRectF& viewPort) const;
	QRectF _CanvasViewPort() const;

	void _PaintLocal(const QRect& viewPort, QPixmap& target) const;

	void _RePaintGroupPixmap();

private:
	struct GroupInfo
	{
		explicit GroupInfo(const std::vector<SvgShape*>& group_): group(group_)
		{
		}

		const std::vector<SvgShape*>& group;
		size_t groupMinIdx = -1;
		size_t groupMaxIdx = -1;
		QPixmap lowPixmap; // 下面的， [0, groupMinIdx)
		QPixmap highPixmap; // 上面的， (groupMaxIdx, shapes.size()]
	};

private:
	// 画布属性
	double m_width = CANVAS_DEFAULT_WIDTH;
	double m_height = CANVAS_DEFAULT_HEIGHT;
	double m_scale = 1;
	QPoint m_basePoint = { 0, 0 };

	QColor m_background = CANVAS_DEFAULT_BACKGROUND;

	SvgShapeVec m_shapeVec;

	// 缩放可能也得放进来, 完全放进来外面的矩形框不好画
	QPixmap m_cache;
	// widget 坐标
	QRect m_viewPort; // 显示的区域

	unique_ptr<GroupInfo> m_groupInfo;
};